package com.lab.idea.bl.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.system.SystemUtil;
import com.lab.idea.common.exception.LabException;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * 工具类
 * @author mao
 */
@Slf4j
public class LabUtil {


    /**
     * 规则判定
     * @param rule      规则
     * @param value     值 - 数字类型
     * @param args       环境参数
     * @return          是否满足
     */
    public static boolean judge(String rule, String value, Map<String,Object> args){
        if (StrUtil.isBlankIfStr(rule) || StrUtil.isBlankIfStr(value)) {
            return false;
        }
        BigDecimal val = Convert.toBigDecimal(value);
        if (val == null) {
            return false;
        }
        if (StrUtil.contains(rule,"±") || StrUtil.contains(rule,"~")) {
            List<BigDecimal> scope = getScope(rule);
            return val.compareTo(scope.get(0)) >= 0 && val.compareTo(scope.get(1)) <= 0;
        } else if (StrUtil.contains(rule,"@")) {
            BlJudge blJudge = new BlJudge();
            return blJudge.judge(rule,value,new JSONObject(args));
        } else if (StrUtil.contains(rule,">")) {
            BigDecimal bigDecimal = Convert.toBigDecimal(StrUtil.subAfter(rule, ">", false));
            return bigDecimal != null && val.compareTo(bigDecimal) > 0;
        } else if (StrUtil.contains(rule,"<")) {
            BigDecimal bigDecimal = Convert.toBigDecimal(StrUtil.subAfter(rule, "<", false));
            return bigDecimal != null && val.compareTo(bigDecimal) > 0;
        } else if (StrUtil.contains(rule,"=")) {
            BigDecimal bigDecimal = Convert.toBigDecimal(StrUtil.subAfter(rule, "=", false));
            return bigDecimal != null && val.compareTo(bigDecimal) == 0;
        } else if (StrUtil.contains(rule,"≥")) {
            BigDecimal bigDecimal = Convert.toBigDecimal(StrUtil.subAfter(rule, "≥", false));
            return bigDecimal != null && val.compareTo(bigDecimal) >= 0;
        } else if (StrUtil.contains(rule,"≤")) {
            BigDecimal bigDecimal = Convert.toBigDecimal(StrUtil.subAfter(rule, "≤", false));
            return bigDecimal != null && val.compareTo(bigDecimal) <= 0;
        }
        return false;
    }

    /**
     * 范围值获取。
     * 支持 x ~ y | x ± x
     *
     * @param scopeStr      范围字符串
     * @return              开始和结束值
     */
    public static List<BigDecimal> getScope(String scopeStr){
        List<BigDecimal> values = new ArrayList<>();
        if (StrUtil.isBlankIfStr(scopeStr)){
            return values;
        }
        List<String> split = StrUtil.split(scopeStr, '~');
        if (split.size() == 2) {
            values.add(Convert.toBigDecimal(split.get(0)));
            values.add(Convert.toBigDecimal(split.get(1)));
        } else {
            split = StrUtil.split(scopeStr, '±');
            if (split.size() == 2) {
                BigDecimal center = Convert.toBigDecimal(split.get(0));
                BigDecimal count = Convert.toBigDecimal(split.get(1));
                values.add(center.subtract(count));
                values.add(center.add(count));
            } else {
                throw new LabException(String.format("%s 写法错误",scopeStr));
            }
        }
        return values;
    }


    /**
     * 有效数字
     * @param val       值
     * @param count     位数
     * @return          值
     */
    public static BigDecimal roundHalfEvenV1(BigDecimal val, int count) {
        // 整数部分
        int intVal = val.intValue();
        int length = Integer.toString(intVal).length();
        // 负数时去掉以为符号位
        if (intVal < 0) {
            length --;
        }
        int scale = intVal != 0 ? count - length : count;
        if (scale > 0) {
            return val.setScale(scale, RoundingMode.HALF_EVEN);
        } else {
            return val.setScale(0, RoundingMode.HALF_EVEN);
        }
    }

    /**
     * 有效数字
     * @param val       值
     * @param count     位数
     * @return          值
     */
    public static BigDecimal roundHalfEven(BigDecimal val, int count) {
        if (val.compareTo(BigDecimal.ZERO) < 0) {
            return BigDecimal.ZERO;
        }
        return roundHalfEvenV1(val,count);
    }

    /**
     * 打开浏览器
     * @param url   打开地址
     */
    public static void openBrowse(String url){
        if (java.awt.Desktop.isDesktopSupported() && SystemUtil.getOsInfo().isWindows()) {
            try {
                // 创建一个URI实例
                java.net.URI uri = java.net.URI.create(url);
                // 获取当前系统桌面扩展
                java.awt.Desktop dp = java.awt.Desktop.getDesktop();
                // 判断系统桌面是否支持要执行的功能
                if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) {
                    // 获取系统默认浏览器打开链接
                    dp.browse(uri);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
//        log.info("0.395:{}",roundHalfEven(new BigDecimal("0.395"),3));
//        log.info("-0.395:{}",roundHalfEven(new BigDecimal("-0.395"),3));
//        log.info("1.395:{}",roundHalfEven(new BigDecimal("1.395"),3));
//        log.info("123.395:{}",roundHalfEven(new BigDecimal("123.395"),3));
//        log.info("-35.629:{}",roundHalfEven(new BigDecimal("-35.629"),3));
//        openBrowse("http://localhost:10000");

        String rule = "@test + @test2 < @test3";
        String value = "1";
        JSONObject env = new JSONObject().set("test",3).set("test2","34").set("test3",36);

        BlJudge blJudge = new BlJudge();
        log.info("{} {}->{},",value,rule,blJudge.judge(rule,value,env));
    }

}
